/*
 * AbstractIMonaReader.java
 *
 * Created on 2007/03/28 +0900
 *
 * $Revision: 38 $
 * $Date: 2008-10-11 08:48:45 +0000 (Sat, 11 Oct 2008) $
 */

package org.gikolet.bbs.imona.reader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.gikolet.bbs.imona.IMonaProperties;
import org.gikolet.framework.io.http.HttpConnection;
import org.gikolet.framework.io.http.HttpConnectionProvider;
import org.gikolet.framework.util.Assert;
import org.gikolet.framework.util.NullProgressMonitor;
import org.gikolet.framework.util.ProgressMonitor;

/**
 * @author Tetsutaro (latest modification by $Author: tetsutaro.ss $)
 * @version $Revision: 38 $ $Date: 2008-10-11 08:48:45 +0000 (Sat, 11 Oct 2008) $
 */
public class AbstractIMonaReader {
    private IMonaProperties properties;
    private HttpConnectionProvider httpConnectionProvider;

    private int bufferSize;

    /**
     *
     */
    public AbstractIMonaReader(IMonaProperties properties) {
	this(properties, 4096);
    }

    public AbstractIMonaReader(IMonaProperties properties, int bufferSize) {
	Assert.isNotNull(properties);

	if (bufferSize <= 0) {
	    throw new IllegalArgumentException("bufferSize is illegal.");
	}

	this.properties = properties;
	this.bufferSize = bufferSize;
    }

    public HttpConnectionProvider getHttpConnectionProvider() {
	return this.httpConnectionProvider;
    }

    public void setHttpConnectionProvider(HttpConnectionProvider httpConnectionProvider) {
	this.httpConnectionProvider = httpConnectionProvider;
    }

    public IMonaProperties getIMonaProperties() {
	return this.properties;
    }

    public void setIMonaProperties(IMonaProperties properties) {
	Assert.isNotNull(properties);

	this.properties = properties;
    }

    public int getBufferSize() {
	return this.bufferSize;
    }

    protected byte[] read(String request, ProgressMonitor progressMonitor)
	    throws IOException {
	if (progressMonitor == null) {
	    progressMonitor = NullProgressMonitor.INSTANCE;
	}

	IMonaProperties properties = this.properties;
	Assert.isNotNull(properties);

	HttpConnectionProvider httpConnectionProvider = this.httpConnectionProvider;
	Assert.isNotNull(httpConnectionProvider);

	String version = "v=F";
	String option = "p=" + properties;

	request = version + "&" + option + "&" + request;

	HttpConnection hc = null;
	try {
	    byte[] requestSJISBytes = ReaderUtilities.toShift_JISBytes(request);

	    hc = httpConnectionProvider.openHttpConnection(properties.getCgi2Url());

	    hc.setRequestMethod(HttpConnection.POST);
	    hc.setRequestProperty("Content-Length", String
		    .valueOf(requestSJISBytes.length));

	    OutputStream out = null;
	    try {
		out = hc.openOutputStream();
		out.write(requestSJISBytes);
	    } finally {
		if (out != null) {
		    try {
			out.close();
		    } catch (IOException ioe) {
		    }
		}
	    }

	    int responseCode = hc.getResponseCode();
	    if (responseCode != HttpConnection.HTTP_ACCEPTED) {
		throw new IOException("Response Code is " + responseCode + ".");
	    }

	    InputStream in = null;
	    try {
		in = hc.openInputStream();

		ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
		byte[] buffer = new byte[this.bufferSize];
		int t = 0;
		while ((t = in.read(buffer)) != -1) {
		    bytesOut.write(buffer, 0, t);
		}
		bytesOut.flush();
		bytesOut.close();

		// progressMonitor.done();

		return bytesOut.toByteArray();
	    } finally {
		if (in != null) {
		    try {
			in.close();
		    } catch (IOException ioe) {
		    }
		}
	    }
	} finally {
	    if (hc != null) {
		try {
		    hc.close();
		} catch (IOException ioe) {
		}
	    }
	}
    }
}
